package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	deadlock()
	deadlockChan()
	deadlockChan1()
	deadlockChan2()
	time.Sleep(3 * time.Second)
}

// all goroutines are asleep - deadlock!
// main执行不下去了，死锁
func deadlock() {
	mutex := sync.Mutex{}
	for i := 0; i < 10; i++ {
		mutex.Lock()
		defer mutex.Unlock()
		fmt.Println("noLock: ", i)
	}
}

func deadlockChan() {
	c := make(chan int)
	// main函数go语言中本身就是一个协程, 在执行到c <- 1的时候，执行main函数的协程将被阻塞
	// 因为c是一个无缓冲通道,写不进去，main函数执行不下去了，整个程序阻塞，发生死锁
	c <- 1
	//go fmt.Println(<-c)
}

// 这个就不会死锁
func deadlockChan1() {
	c := make(chan int, 1)
	c <- 1
	fmt.Println(<-c)
}

// 这个也不会死锁, 因为这个通道有缓冲，可以写进去
func deadlockChan2() {
	c := make(chan int, 1)
	go func() { c <- 1 }()
	go fmt.Println(<-c)
}
